home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
lib
/
mntlib44.zoo
/
mntlib
/
crtinit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-27
|
13KB
|
494 lines
/*
*
* Crtinit: C run-time initialization code.
* Written by Eric R. Smith, and placed in the public domain.
* Use at your own risk.
*
* 01/03/89 ++jrb
* The (new) meaning of _stksize: (thanks to allan pratt for the feedback)
*
* _stksize meaning
* -1L keep all of memory (except MINFREE at top) and do
* mallocs from own heap, with heap grown upwards towards
* stack, and the stack growing down towards heap,
* with a minimum slush between them so that they
* dont meet (only checked while malloc'ing). With
* this model, further spawning is not possible, but it is
* well suited for programs such as gcc-cc1 etc.
* Thanks to Piet van Oostrum & Atze Dijkstra for this idea
*
* 0L keep minimum amount of memory. this is also the
* case when _stksize is undefined by the user.
* 1L keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART)
* 2L keep 2/4 (1/2), free rest
* 3L keep 3/4, free 1/4
* other keep that many bytes
* -other keep |other| bytes, use the heap for mallocs
*
* 02/14/90 ++jrb (thanks edgar)
* auto acc detect
* undump friendly
*
* NOTE: dumping applications should use _initial_stack instead: if
* !=0, then _stksize is initialized from _initial_stack, and
* mallocs are always from internal heap. (TeX works much better now),
* thanks edgar!
*
* Acc convention:
* Preferred: user sets _stksize, then _heapbase is set to Malloc(_stksize)
* sp to _heapbase + _stksize and all mallocs happen from heap
*
* Old way:
* user sets _heapbase to bottom of stack + heap area
* sets _stksize to the size of this area
* at startup, sp will be set to top of this area
* (_heapbase + _stksize ) and malloc()'s will happen from heap.
* (note malloc() and *not* Malloc())
*
* 02/16/90 ++jrb
* - bug fix: dont get screwed by desktop launch when fast bit is set
* convert env string to format usable
* (atari get your act together!!)
*
* 09-20-92 hyc
* Support base relative addressing, for shared-text execution.
* Also merged in some stuff from ++jrb's crt0.c.
*
* Turbo / Pure C version 21-6-92 um
* the Turbo / Pure linker reserves stack space in the BSS and sets
* the symbol _StkSize to its size. If _StkSize is set to 0, we use
* _stksize etc. as usual
*
* 19 Jan 93 hohmuth
* new variable _PgmSize, holds size of program area
* (useful when doing Ptermres)
*
* 08 Apr 93 hohmuth
* added support for ARGV standard extension allowing empty arguments
*
*/
/* define this symbol to get ARGV argument passing that's strictly
* compatible with the Atari standard. If it's not defined, then
* the startup code won't validate the ARGV= variable by checking
* the command byte for 0x127. Note that there are still some
* applications (gulam is a notable example) that implement only
* part of the standard and don't set the command byte to 0x127.
*/
#if 0
#define STRICTLY_COMPATIBLE_WITH_STANDARD
#endif
#include <basepage.h>
#include <osbind.h>
#include <support.h>
#include "lib.h"
#define isspace(c) ((c) == ' '||(c) == '\t')
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define MINFREE (8L * 1024L) /* free at least this much mem */
/* on top */
#define MINKEEP (8L * 1024L) /* keep at least this much mem */
BASEPAGE *_base;
char **environ;
static long argc;
static char **argv;
/* size to be allocated for the stack */
extern long _stksize; /* picked up from user or from stksiz.c */
/* set to heap base addr when _stksize < 0 || _initial_stack || When DA
* note that we allow the user to provide a _heapbase of their own, since
* that used to be necessary for acc's; but that is no longer needed
* (or encouraged) since the acc startup code now Mallocs a heap
* automatically
*/
extern void *_heapbase; /* picked up from user or from heapbase.c */
/*
* initial stack is used primarily by dumping application,
* if it is, malloc is always from heap, and _stksize is init
* from initial_stack (to preserve the value in the undumped run)
*/
extern long _initial_stack; /* picked up from user or from inistack.c */
unsigned long _PgmSize; /* total size of program area */
#ifdef __TURBOC__
char *_StkLim; /* for Turbo / Pure C stack checking */
extern _StkSize; /* set by linker */
#endif
/* default sizeof stdio buffers */
size_t __DEFAULT_BUFSIZ__; /* .comm */
/* are we an app? */
short _app;
/* are we on a split addr mem ST */
short _split_mem = 0;
static long parseargs __PROTO((BASEPAGE *));
/*
* accessories start here:
*/
static char *acc_argv[] = {"", (char *) 0}; /* no name and no arguments */
void _acc_main()
{
#ifdef __TURBOC__
if (&_StkSize == 0)
{
#endif
if (_stksize == 0 || _stksize == -1L)
_stksize = MINKEEP;
if (_stksize < 0)
_stksize = -_stksize;
_stksize &= 0xfffffffeL; /* stack on word boundary */
#ifdef __TURBOC__
}
else
{
/* This compound statement is executed if the Pure linker
has reserved space for the stack in the BSS */
_stksize = (long) &_StkSize;
_heapbase = _base->p_bbase + _base->p_blen - _stksize;
}
_StkLim = (char *) _heapbase + 256; /* for stack checking */
#endif
if (_heapbase == 0) {
_heapbase = (void *)Malloc(_stksize);
}
_setstack((char *) _heapbase + _stksize);
_app = 0; /* this is an accessory */
_main(1L, acc_argv, acc_argv);
/*NOTREACHED*/
}
void _crtinit()
{
register BASEPAGE *bp;
register long m;
register long freemem;
#ifdef __GNUC__
extern void etext(); /* a "function" to fake out pc-rel addressing */
#endif
_app = 1; /* its an application */
if(!__DEFAULT_BUFSIZ__)
__DEFAULT_BUFSIZ__ = BUFSIZ;
bp = _base;
m = parseargs(bp); /* m = # bytes used by environment + args */
/* make m the total number of bytes required by program sans stack/heap */
m += (bp->p_tlen + bp->p_dlen + bp->p_blen + sizeof(BASEPAGE));
m = (m + 3L) & (~3L);
#ifdef __TURBOC__
if (&_StkSize == 0)
{
#endif
/* freemem the amount of free mem accounting for MINFREE at top */
if((freemem = (long)bp->p_hitpa - (long)bp - MINFREE - m) <= 0L)
goto notenough;
if(_initial_stack)
{
/* the primary use of _initial_stack will be in dumping */
/* applications where only a heap for malloc makes sense */
_heapbase = (void *) ((long)bp + m);
_stksize = _initial_stack;
} else {
if (_stksize >= -1L)
_split_mem = 1; /* malloc from Malloc first, then from own heap */
}
if (_stksize == -1L) {
_stksize = freemem;
_heapbase = (void *) ((long)bp + m);
} else if (_stksize == 0L) { /* free all but MINKEEP */
_stksize = MINKEEP;
} else if (_stksize == 1L) { /* keep 1/4, free 3/4 */
_stksize = freemem >> 2;
} else if (_stksize == 2L) { /* keep 1/2, free 1/2 */
_stksize = freemem >> 1;
} else if (_stksize == 3L) { /* keep 3/4, free 1/4 */
_stksize = freemem - (freemem >> 2);
} else {
if(_stksize < -1L) { /* keep |_stksize|, use heap for mallocs */
_stksize = -_stksize;
_heapbase = (void *)((long)bp + m);
}
}
/* make m the total number of bytes including stack */
_stksize = _stksize & (~3L);
m += _stksize;
/* make sure there's enough room for the stack */
if (((long)bp + m) > ((long)bp->p_hitpa - MINFREE))
goto notenough;
/* set up the new stack to bp + m */
#ifdef __TURBOC__
{
char *tmp;
tmp = (char *) bp + m;
_setstack(tmp);
_StkLim = tmp - _stksize + 256; /* for stack checking */
}
#else
_setstack((char *)bp + m);
#endif
#ifdef __TURBOC__
} /* if (&_StkSize == 0) */
else
{
/* This compound statement is executed if the Pure linker
has reserved space for the stack in the BSS */
_stksize = (long) &_StkSize;
_stksize = _stksize & (~3L);
{
char *tmp;
tmp = (char *) bp->p_bbase + bp->p_blen;
_setstack(tmp);
_StkLim = tmp - _stksize + 256; /* for stack checking */
_heapbase = NULL; /* no mallocs from heap */
}
}
#endif /* __TURBOC__ */
/* shrink the TPA */
(void)Mshrink(bp, m);
/* keep length of program area */
_PgmSize = m;
/* establish handlers, call the main routine */
_init_signal();
/* start profiling, if we were linked with gcrt0.o */
#ifdef __GNUC__
_monstart